package com.ruoyi.project.wf.service.impl;

import java.sql.Date;
import java.util.List;

import com.ruoyi.common.constant.PaeaConstants;
import com.ruoyi.common.utils.DateUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.project.system.parawork.domain.PaeaTaskLimitPara;
import com.ruoyi.project.system.parawork.service.IPaeaTaskLimitParaService;
import com.ruoyi.project.wf.domain.*;
import com.ruoyi.project.wf.enums.WfProcessActType;
import com.ruoyi.project.wf.enums.WfProcessInstStatus;
import com.ruoyi.project.wf.enums.WfWorkItemStatus;
import com.ruoyi.project.wf.model.WfWorkItemModel;
import com.ruoyi.project.wf.model.WorkitemSubmitDataWrapper;
import com.ruoyi.project.wf.service.IWfActBranchService;
import com.ruoyi.project.wf.service.IWfProcessActService;
import com.ruoyi.project.wf.service.IWfProcessInstService;
import org.springframework.stereotype.Service;
import com.ruoyi.project.wf.mapper.WfWorkItemMapper;
import com.ruoyi.project.wf.service.IWfWorkItemService;
import com.ruoyi.common.utils.text.Convert;

import javax.annotation.Resource;

/**
 * 流程审批信息Service业务层处理
 *
 * @author XQ.XU
 * @date 2020-03-20
 */
@Service
public class WfWorkItemServiceImpl extends ServiceImpl<WfWorkItemMapper, WfWorkItem> implements IWfWorkItemService
{
    @Resource
    private WfWorkItemMapper wfWorkItemMapper;
    @Resource
    private IPaeaTaskLimitParaService paeaTaskLimitParaService;
    @Resource
    private IWfActBranchService wfActBranchService;
    @Resource
    private IWfProcessInstService wfProcessInstService;
    @Resource
    private IWfProcessActService wfProcessActService;
    /**
     * 查询流程审批信息
     *
     * @param id 流程审批信息ID
     * @return 流程审批信息
     */
    @Override
    public WfWorkItem selectWfWorkItemById(String id)
    {
        return wfWorkItemMapper.selectWfWorkItemById(id);
    }

    /**
     * 查询流程审批信息列表
     *
     * @param wfWorkItem 流程审批信息
     * @return 流程审批信息
     */
    @Override
    public List<WfWorkItem> selectWfWorkItemList(WfWorkItem wfWorkItem)
    {
        return wfWorkItemMapper.selectWfWorkItemList(wfWorkItem);
    }

    /**
     * 新增流程审批信息
     *
     * @param wfWorkItem 流程审批信息
     * @return 结果
     */
    @Override
    public int insertWfWorkItem(WfWorkItem wfWorkItem)
    {
        wfWorkItem.setCreateTime(DateUtils.getNowDate());
        return wfWorkItemMapper.insertWfWorkItem(wfWorkItem);
    }

    /**
     * 修改流程审批信息
     *
     * @param wfWorkItem 流程审批信息
     * @return 结果
     */
    @Override
    public int updateWfWorkItem(WfWorkItem wfWorkItem)
    {
        wfWorkItem.setUpdateTime(DateUtils.getNowDate());
        return wfWorkItemMapper.updateWfWorkItem(wfWorkItem);
    }

    /**
     * 删除流程审批信息对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteWfWorkItemByIds(String ids)
    {
        return wfWorkItemMapper.deleteWfWorkItemByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除流程审批信息信息
     *
     * @param id 流程审批信息ID
     * @return 结果
     */
    @Override
    public int deleteWfWorkItemById(String id)
    {
        return wfWorkItemMapper.deleteWfWorkItemById(id);
    }
    @Override
    public int deleteWfWorkItemByProcInstId(String procInstId) {
        return wfWorkItemMapper.deleteWfWorkItemByProcInstId(procInstId);
    }



    public List<WfWorkItem> findStartWfWorkItems(String procInstId,Date trDate) {
        //String hql = "from WfWorkItem entity where entity.wfProcessInst.id=? and entity.wfProcessAct.actType=?";
        WfWorkItemModel vo= new WfWorkItemModel();
        vo.setActType(WfProcessActType.Start.getValue());
        vo.setProcInstId(procInstId);
        List<WfWorkItem> startWorkitems=wfWorkItemMapper.selectWfWorkItemByActType(vo);

        //List<WfWorkItem> startWorkitems =(List) wfWorkItemDao.find(hql, new Object[] {processInstId, WfProcessActType.Start.getValue() });
        return startWorkitems;
    }
    public WfWorkItem submitStartWfWorkItem( String wfProcessInstId, Date trDate) {
        WfProcessInst wfProcessInst=wfProcessInstService.selectWfProcessInstById(wfProcessInstId);
        return submitStartWfWorkItem(wfProcessInst,trDate);
    }
    public WfWorkItem submitStartWfWorkItem( WfProcessInst wfProcessInst,Date trDate) {

        WfProcessAct wfProcessAct=wfProcessActService.selectStartNode(wfProcessInst.getProcDefId(),WfProcessActType.Start.getValue() );
        if (wfProcessAct == null ) {
            //TODO: 异常如何处理？
            //throw new BizException("该流程不能确定起始点");
        }
        WfWorkItem wfWorkItem = new WfWorkItem();
        wfWorkItem.setProcInstId(wfProcessInst.getId());
        wfWorkItem.setProcActId(wfProcessAct.getId());
        wfWorkItem.setCreateTime(new java.sql.Date(System.currentTimeMillis()));
        wfWorkItem.setCode(wfProcessAct.getCode());
        wfWorkItem.setName(wfProcessAct.getName());
        wfWorkItem.setStatus(WfWorkItemStatus.Created.getValue());
        saveOrUpdate(wfWorkItem);
        //查询扩展信息
        wfWorkItem=selectWfWorkItemById(wfWorkItem.getId());
        WorkitemSubmitDataWrapper workitemResultDataWrapper = new WorkitemSubmitDataWrapper();

        List<WfActBranch> wfActBranches=  wfProcessAct.getWfActBranchsByFromProcActId();
        if (wfActBranches.size() == 0) {
            //TODO:异常处理
            //throw new BizException("该流程配置不正确，没有起始点");
        } else if (wfActBranches.size() > 1) {
            //throw new BizException("该流程配置不正确，起始点超过一个");
        }
        for (WfActBranch branch : wfActBranches) {
            workitemResultDataWrapper.parameterName_valueMap.put("nextWfProcessActId", branch.getToProcActId());
        }

        return this.submitWfWorkItem(wfWorkItem,workitemResultDataWrapper,trDate);
    }

    // 提交流程,返回下一个节点工作项
    public WfWorkItem submitWfWorkItem( String workitemId,WorkitemSubmitDataWrapper workitemResultDataWrapper, Date trDate) {
        // 把数据提交给workitem，并修改状态
        WfWorkItem wfWorkItem = wfWorkItemMapper.selectWfWorkItemById(workitemId);

        WfWorkItem nextWfWorkItem = this.submitWfWorkItem(wfWorkItem,workitemResultDataWrapper, trDate);

        return nextWfWorkItem;
    }
    // 提交流程，返回下一个节点工作项
    public WfWorkItem submitWfWorkItem( WfWorkItem wfWorkItem,WorkitemSubmitDataWrapper workitemResultDataWrapper, Date trDate) {
        // 把数据提交给workitem，并修改状态

        if (wfWorkItem == null) {
            //TODO:异常处理
           // throw new BizException("没有找到任务，可能被删除");
        }
        if (wfWorkItem.getOperId() != null&& ShiroUtils.getUserId().equals(wfWorkItem.getOperId()) == false
               // &&!smUser.getSmSystemRoles().get(0).getRoleCode().equals(PaeaUserRole.扫描员.getRoleCode())
        )
        {
            //TODO：异常处理
            //throw new BizException("任务可能被其他人获取");
        }
        if (wfWorkItem.getOperId() != null && wfWorkItem.getStatus() != WfWorkItemStatus.Acquired.getValue()) {
            //TODO：异常处理
           // throw new BizException("任务不在获取状态，不能提交");
        }
        wfWorkItem.setJudgeValue((String) workitemResultDataWrapper.parameterName_valueMap.get("judgeValue"));
        wfWorkItem.setRemarkValue((String) workitemResultDataWrapper.parameterName_valueMap.get("remarkValue"));
        wfWorkItem.setOperCode(ShiroUtils.getUserId());
        wfWorkItem.setOperName(ShiroUtils.getLoginName());
        wfWorkItem.setOperId(ShiroUtils.getUserId());

        wfWorkItem.setFinishedTime(new java.sql.Date(System.currentTimeMillis()));

        String code = wfWorkItem.getCode();
        //int dueDays = 6;
        PaeaTaskLimitPara limitPara = new PaeaTaskLimitPara();
        limitPara.setCode(PaeaConstants.ERROR);
        PaeaTaskLimitPara paeaTaskLimitPara=(PaeaTaskLimitPara) paeaTaskLimitParaService.selectPaeaTaskLimitParaList(limitPara).get(0);
        int dueDays = paeaTaskLimitPara.getLimit();

		/*if ("1001".equals(code)) {
			dueDays = 6;
		}*/
        // 检查是否超过处理时间期限
        boolean isDelayed = false;
        if (wfWorkItem.getCreateTime() != null) {
            long time = System.currentTimeMillis()- wfWorkItem.getCreateTime().getTime();
            isDelayed = (time - dueDays * 24 * 3600 * 1000L) > 0;
        }
        wfWorkItem.setStatus(isDelayed ? WfWorkItemStatus.DelayFinished.getValue() : WfWorkItemStatus.Finished.getValue());
        // 写完成日志
        WfProcessAct oldWfProcessAct=wfProcessActService.selectWfProcessActById(wfWorkItem.getProcActId());
        if (oldWfProcessAct.getActType() != WfProcessActType.Start.getValue()) {
            //TODO写日志
            //servicePaeaReportBusinessImpl.savePaeaReportBusiness(smUser,new java.util.Date(), 0, 0, 0, 0, 0, 1, isDelayed ? 1 : 0,0,0);
        }
        this.updateWfWorkItem(wfWorkItem);

        // 产生下一个任务
        String nextActId = (String) workitemResultDataWrapper.parameterName_valueMap.get("nextWfProcessActId");
        if (nextActId == null || nextActId.length() == 0) {
            // 为空表示流程结束
            WfProcessInst wfProcessInst = wfProcessInstService.selectWfProcessInstById(wfWorkItem.getProcInstId());
            wfProcessInst.setStatus(WfProcessInstStatus.Finished.getValue());
            wfProcessInst.setFinishedTime(new java.sql.Date(System.currentTimeMillis()));
            wfProcessInstService.updateWfProcessInst(wfProcessInst);
            return null;
        } else {
            // 流程未结束
//			WfWorkItem newWorkitem = this.serviceWfWorkItemImpl.createWfWorkItem(trDate);
            WfWorkItem newWorkitem=new WfWorkItem();
           // ThreadLocalCommon.setSuffix(DateTimeUtil.getYYMM(trDate));
            WfProcessAct wfProcessAct = wfProcessActService.selectWfProcessActById(nextActId);
            newWorkitem.setProcActId(nextActId);
            newWorkitem.setProcInstId(wfWorkItem.getProcInstId());
            newWorkitem.setCode(wfProcessAct.getCode());
            newWorkitem.setName(wfProcessAct.getName());
            newWorkitem.setCreateTime(new java.sql.Date(System.currentTimeMillis()));
            if ("end".equals(wfProcessAct.getCode())) { // 表示流程已经结束
                newWorkitem.setStatus(WfWorkItemStatus.Finished.getValue());
                newWorkitem.setFinishedTime(new java.sql.Date(System.currentTimeMillis()));
                WfProcessInst wfProcessInst = wfProcessInstService.selectWfProcessInstById(wfWorkItem.getProcInstId());
                wfProcessInst.setStatus(WfProcessInstStatus.Finished.getValue());
                wfProcessInst.setFinishedTime(new java.sql.Date(System.currentTimeMillis()));
                wfProcessInstService.updateWfProcessInst(wfProcessInst);
            } else {
                newWorkitem.setStatus(WfWorkItemStatus.Created.getValue());

            }
            this.saveOrUpdate(newWorkitem);

            return newWorkitem;
        }

    }
    @Override
    public List<WfWorkItem> selectWfWorkItemsByErrId(String errId) {
        return wfWorkItemMapper.selectWfWorkItemsByErrId(errId);
    }

}
